//! \file pairsocket.hpp
//! \brief Purewell Library Pair Socket Header
//! \author Yubin Lim (purewell@gmail.com)
//! \since 2008-01-25

#ifndef __PWHDR_PAIRSOCKET_HPP__
#define __PWHDR_PAIRSOCKET_HPP__

#include "pairfile.hpp"
#include "socket.hpp"

namespace purewell
{

//! \brief Pair socket.
class PWAPI PWPairSocket : public PWPairFile
{
public:
	//! \brief Initialize pair socket.
	//! \param[in] name Socket file name.
	//! \param[in] flags Flags.
	//! \param[in] omode Open modes.
	virtual bool initialize(const char* name, int flags, int omode);

public:
	//! \brief Receive packet from socket.
	//! \param[out] buf Buffer.
	//! \param[in] blen Buffer length.
	//! \param[in] flag Flags.
	//! \param[in] idx File descriptor index.
	//! \return Operated size or -1.
	virtual ssize_t receive(void* buf, size_t blen, int flag, size_t idx);

	//! \brief Send packet from socket.
	//! \param[in] buf Buffer.
	//! \param[in] blen Buffer length.
	//! \param[in] flag Flags.
	//! \param[in] idx File descriptor index.
	//! \return Operated size or -1.
	virtual ssize_t send(const void* buf, size_t blen,
		int flag, size_t idx);

	virtual ssize_t read(void* buf, size_t blen, size_t idx);
	virtual ssize_t write(const void* buf, size_t blen, size_t idx);
	virtual void destroy(void);

	//! \brief Get socket option.
	//! \param[out] v Value.
	//! \param[out] vlen Value length. (optional)
	//! \param[in] lv Level.
	//! \param[in] optname Option name.
	//! \param[in] idx Index.
	//! \return On success, true.
	bool getOption(void* v, size_t* vlen, int lv,
		int optname, size_t idx) const;

	//! \brief Get socket option by boolean.
	//! \param[out] b Result.
	//! \param[in] lv Level.
	//! \param[in] optname Option name.
	//! \param[in] idx Index.
	//! \return On success, true.
	bool getOptionBoolean(bool& b, int lv, int optname, size_t idx) const;

	//! \brief Get socket option by 32bit-integer.
	//! \param[out] i Result.
	//! \param[in] lv Level.
	//! \param[in] optname Option name.
	//! \param[in] idx Index.
	//! \return On success, true.
	bool getOptionInteger32(int32_t& i, int lv,
		int optname, size_t idx) const;

	//! \brief Get socket option by 64-integer.
	//! \param[out] i Result.
	//! \param[in] lv Level.
	//! \param[in] optname Option name.
	//! \param[in] idx Index.
	//! \return On success, true.
	bool getOptionInteger64(int64_t& i, int lv,
		int optname, size_t idx) const;

	//! \brief Set socket option.
	//! \param[out] v Value.
	//! \param[out] vlen Value length.
	//! \param[in] lv Level.
	//! \param[in] optname Option name.
	//! \param[in] idx Index.
	//! \return On success, true.
	bool setOption(const void* v, size_t vlen, int lv,
		int optname, size_t idx);

	//! \brief Set socket option by boolean.
	//! \param[in] b Value.
	//! \param[in] lv Level.
	//! \param[in] optname Option name.
	//! \param[in] idx Index.
	//! \return On success, true.
	bool setOptionBoolean(bool b, int lv, int optname, size_t idx);

	//! \brief Set socket option by 32bit-integer.
	//! \param[in] i Value.
	//! \param[in] lv Level.
	//! \param[in] optname Option name.
	//! \param[in] idx Index.
	//! \return On success, true.
	bool setOptionInteger32(int32_t i, int lv, int optname, size_t idx);

	//! \brief Set socket option by 64bit-integer.
	//! \param[in] i Value.
	//! \param[in] lv Level.
	//! \param[in] optname Option name.
	//! \param[in] idx Index.
	//! \return On success, true.
	bool setOptionInteger64(int64_t i, int lv, int optname, size_t idx);

	//! \brief Get reuse-address flag.
	//! \param[in] idx Index.
	//! \return On set, true.
	bool getOptionReuseAddress(size_t idx) const;

	//! \brief Set reuse-address flag.
	//! \param[in] v Value.
	//! \param[in] idx Index.
	//! \return On success, true.
	bool setOptionReuseAddress(bool v, size_t idx);

	//! \brief Get keep-alive flag.
	//! \param[in] idx Index.
	//! \return On set, true.
	bool getOptionKeepAlive(size_t idx) const;

	//! \brief Set keep-alive flag.
	//! \param[in] v Value.
	//! \param[in] idx Index.
	//! \return On success, true.
	bool setOptionKeepAlive(bool v, size_t idx);

	//! \brief Get receive buffer size.
	//! \param[in] idx Index.
	//! \return On success, buffer size or zero.
	size_t getOptionReceiveBuffer(size_t idx) const;

	//! \brief Set receive buffer size.
	//! \param[in] size Size.
	//! \param[in] idx Index.
	//! \return On success, true.
	bool setOptionReceiveBuffer(size_t size, size_t idx);

	//! \brief Get send buffer size.
	//! \param[in] idx Index.
	//! \return On success, buffer size or zero.
	size_t getOptionSendBuffer(size_t idx) const;

	//! \brief Set send buffer size.
	//! \param[in] size Size.
	//! \param[in] idx Index.
	//! \return On success, true.
	bool setOptionSendBuffer(size_t size, size_t idx);

	//! \brief Get use-nagle flag.
	//! \param[in] idx Index.
	//! \return On set, true.
	bool getOptionDelay(size_t idx) const;

	//! \brief Set use-nagle flag.
	//! \param[in] v Value.
	//! \param[in] idx Index.
	//! \return On success, true.
	bool setOptionDelay(bool v, size_t idx);

public:
	explicit PWPairSocket();
	virtual ~PWPairSocket();
};

};

#endif//!__PWHDR_PAIRSOCKET_HPP__

